package com.cqhz.quwan.util;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class FootBallBetUtils
{

    //选球投注号对应比赛结果 APP端
    public static       Map<Integer, String>          scoreMap     = new HashMap<>();
    //比赛结果对应投注号 后端
    public static       Map<String, Integer>          ballMap      = new HashMap<>();
    //胜平负
    public static final Integer[]                     spfKey       = {0, 1, 2};
    //让球胜平负
    public static final Integer[]                     rqspfKey     = {3, 4, 5};
    //半全场
    public static final Integer[]                     bqcKey       = {6, 7, 8, 9, 10, 11, 12, 13, 14};
    //比分
    public static final Integer[]                     bfKey        = {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45};
    //总进球
    public static final Integer[]                     zjqKey       = {46, 47, 48, 49, 50, 51, 52, 53};
    //串玩法
    public static final String[]                      bunchKey     = {
            "2-1", "3-1", "4-1", "5-1", "6-1", "7-1", "8-1",
            "3-3", "3-4",
            "4-4", "4-5", "4-6", "4-11",
            "5-5", "5-6", "5-10", "5-16", "5-20", "5-26",
            "6-6", "6-7", "6-15", "6-20", "6-22", "6-35", "6-42", "6-50", "6-57",
            "7-7", "7-8", "7-21", "7-35", "7-120",
            "8-8", "8-9", "8-28", "8-56", "8-70", "8-247", "8-255"
    };
    //串列表
    public static       List<List<BallBunch>>         bunchList    = new ArrayList<>();
    //串map
    public static       Map<Integer, List<BallBunch>> bunchMap     = new HashMap<>();
    //过关投注对应选球
    public static       Map<String, Integer[]>        betMethodMap = new HashMap<>();
    private static      DecimalFormat                 df           = new DecimalFormat("#.00");

    static
    {
        initScoreMap();
        initBallMap();
        initBunchList();
        initBetMethodMap();
        bunchMap.put(1, new ArrayList<BallBunch>());
        bunchMap.put(2, new ArrayList<BallBunch>());
    }

    private static void initScoreMap()
    {
        //胜平负
        scoreMap.put(0, "主胜");//胜
        scoreMap.put(1, "平");//平
        scoreMap.put(2, "主负");//负
        //让球胜平负
        scoreMap.put(3, "主胜");//让球胜
        scoreMap.put(4, "平");//让球平
        scoreMap.put(5, "主负");//让球负
        //半全场
        scoreMap.put(6, "胜胜");
        scoreMap.put(7, "胜平");
        scoreMap.put(8, "胜负");
        scoreMap.put(9, "平胜");
        scoreMap.put(10, "平平");
        scoreMap.put(11, "平负");
        scoreMap.put(12, "负胜");
        scoreMap.put(13, "负平");
        scoreMap.put(14, "负负");
        //比分-胜
        scoreMap.put(15, "1:0");
        scoreMap.put(16, "2:0");
        scoreMap.put(17, "2:1");
        scoreMap.put(18, "3:0");
        scoreMap.put(19, "3:1");
        scoreMap.put(20, "3:2");
        scoreMap.put(21, "4:0");
        scoreMap.put(22, "4:1");
        scoreMap.put(23, "4:2");
        scoreMap.put(24, "5:0");
        scoreMap.put(25, "5:1");
        scoreMap.put(26, "5:2");
        scoreMap.put(27, "胜其他");
        //比分-平
        scoreMap.put(28, "0:0");
        scoreMap.put(29, "1:1");
        scoreMap.put(30, "2:2");
        scoreMap.put(31, "3:3");
        scoreMap.put(32, "平其他");
        //比分-负
        scoreMap.put(33, "0:1");
        scoreMap.put(34, "0:2");
        scoreMap.put(35, "1:2");
        scoreMap.put(36, "0:3");
        scoreMap.put(37, "1:3");
        scoreMap.put(38, "2:3");
        scoreMap.put(39, "0:4");
        scoreMap.put(40, "1:4");
        scoreMap.put(41, "2:4");
        scoreMap.put(42, "0:5");
        scoreMap.put(43, "1:5");
        scoreMap.put(44, "2:5");
        scoreMap.put(45, "负其他");
        //总进球
        scoreMap.put(46, "0");
        scoreMap.put(47, "1");
        scoreMap.put(48, "2");
        scoreMap.put(49, "3");
        scoreMap.put(50, "4");
        scoreMap.put(51, "5");
        scoreMap.put(52, "6");
        scoreMap.put(53, "7+");
    }

    private static void initBallMap()
    {
        //胜平负
        ballMap.put("胜", 0);//胜
        ballMap.put("平", 1);//平
        ballMap.put("负", 2);//负
        //让球胜平负
        ballMap.put("让球胜", 3);//让球胜
        ballMap.put("让球平", 4);//让球平
        ballMap.put("让球负", 5);//让球负
        //半全场
        ballMap.put("胜胜", 6);
        ballMap.put("胜平", 7);
        ballMap.put("胜负", 8);
        ballMap.put("平胜", 9);
        ballMap.put("平平", 10);
        ballMap.put("平负", 11);
        ballMap.put("负胜", 12);
        ballMap.put("负平", 13);
        ballMap.put("负负", 14);
        //比分-胜
        ballMap.put("1:0", 15);
        ballMap.put("2:0", 16);
        ballMap.put("2:1", 17);
        ballMap.put("3:0", 18);
        ballMap.put("3:1", 19);
        ballMap.put("3:2", 20);
        ballMap.put("4:0", 21);
        ballMap.put("4:1", 22);
        ballMap.put("4:2", 23);
        ballMap.put("5:0", 24);
        ballMap.put("5:1", 25);
        ballMap.put("5:2", 26);
        ballMap.put("胜其他", 27);
        //比分-平
        ballMap.put("0:0", 28);
        ballMap.put("1:1", 29);
        ballMap.put("2:2", 30);
        ballMap.put("3:3", 31);
        ballMap.put("平其他", 32);
        //比分-负
        ballMap.put("0:1", 33);
        ballMap.put("0:2", 34);
        ballMap.put("1:2", 35);
        ballMap.put("0:3", 36);
        ballMap.put("1:3", 37);
        ballMap.put("2:3", 38);
        ballMap.put("0:4", 39);
        ballMap.put("1:4", 40);
        ballMap.put("2:4", 41);
        ballMap.put("0:5", 42);
        ballMap.put("1:5", 43);
        ballMap.put("2:5", 44);
        ballMap.put("负其他", 45);
        //总进球
        ballMap.put("0", 46);
        ballMap.put("1", 47);
        ballMap.put("2", 48);
        ballMap.put("3", 49);
        ballMap.put("4", 50);
        ballMap.put("5", 51);
        ballMap.put("6", 52);
        ballMap.put("7+", 53);
    }

    /**
     * 说    明：
     *
     * @param matchNum 场次个数
     * @param isdg     是否支持单关
     *                 创 建 人：	一刀·胡
     *                 创建时间：	2018/5/3 16:03
     *                 修 改 人：
     *                 修改日期：
     **/
    public static Map<Integer, List<BallBunch>> getBallBunch(int matchNum, int playType, Object[][] betList, boolean isdg)
    {
        bunchMap.get(1).clear();
        bunchMap.get(2).clear();
        // 比分、半全场最多4关
        if (matchNum > 4 && (playType == 3 || playType == 5))
            matchNum = 4;
        // 总进球最多6关
        if (matchNum > 6 && playType == 4)
            matchNum = 6;
        // 混合投注中包含了比分或半全场的，串关方式最多4关
        if (matchNum > 4 && playType == 6)
        {
            Set<Integer> set = new HashSet<>();
            for (Object[] bets : betList)
            {
                for (Object bet : bets)
                    set.add((Integer) bet);
            }
            List<Integer> list = new ArrayList(set);
            Collections.sort(list);
            Collections.reverse(list);
            for (Integer k : list)
            {
                if (k >= zjqKey[0])
                {
                    matchNum = matchNum > 6 ? 6 : matchNum;
                }
                else if (k < zjqKey[0] && k >= bqcKey[0])
                {
                    matchNum = matchNum > 4 ? 4 : matchNum;
                    break;
                }
                else
                {
                    break;
                }
            }
        }
        //最大支持8关
        if (matchNum > 8)
            matchNum = 8;
        //是否单关
        if (isdg)
        {
            bunchMap.get(1).add(new BallBunch("1-1", "单关", false));
        }
        bunchMap.get(1).addAll(bunchList.get(1).subList(0, matchNum - 1));
        for (int m = 3; m <= matchNum; m++)
        {
            bunchMap.get(2).addAll(bunchList.get(m));
        }
        return bunchMap;
    }

    private static void initBunchList()
    {
        for (int i = 0; i < 9; i++)
        {
            bunchList.add(new ArrayList<BallBunch>());
        }
        for (String bunch : bunchKey)
        {
            if (bunch.endsWith("-1"))
            {
                bunchList.get(1).add(new BallBunch(bunch, bunch.replace("-", "串"), false));
                continue;
            }
            if (bunch.startsWith("2-"))
            {
                bunchList.get(2).add(new BallBunch(bunch, bunch.replace("-", "串"), false));
            }
            if (bunch.startsWith("3-"))
            {
                bunchList.get(3).add(new BallBunch(bunch, bunch.replace("-", "串"), false));
            }
            if (bunch.startsWith("4-"))
            {
                bunchList.get(4).add(new BallBunch(bunch, bunch.replace("-", "串"), false));
            }
            if (bunch.startsWith("5-"))
            {
                bunchList.get(5).add(new BallBunch(bunch, bunch.replace("-", "串"), false));
            }
            if (bunch.startsWith("6-"))
            {
                bunchList.get(6).add(new BallBunch(bunch, bunch.replace("-", "串"), false));
            }
            if (bunch.startsWith("7-"))
            {
                bunchList.get(7).add(new BallBunch(bunch, bunch.replace("-", "串"), false));
            }
            if (bunch.startsWith("8-"))
            {
                bunchList.get(8).add(new BallBunch(bunch, bunch.replace("-", "串"), false));
            }
        }
    }

    private static void initBetMethodMap()
    {
        betMethodMap.put("1-1", new Integer[]{1});
        betMethodMap.put("2-1", new Integer[]{2});
        betMethodMap.put("2-3", new Integer[]{1, 2});
        betMethodMap.put("3-1", new Integer[]{3});
        betMethodMap.put("3-3", new Integer[]{2});
        betMethodMap.put("3-4", new Integer[]{2, 3});
        betMethodMap.put("3-6", new Integer[]{1, 2});
        betMethodMap.put("3-7", new Integer[]{1, 2, 3});
        betMethodMap.put("4-1", new Integer[]{4});
        betMethodMap.put("4-4", new Integer[]{3});
        betMethodMap.put("4-5", new Integer[]{3, 4});
        betMethodMap.put("4-6", new Integer[]{2});
        betMethodMap.put("4-10", new Integer[]{1, 2});
        betMethodMap.put("4-11", new Integer[]{2, 3, 4});
        betMethodMap.put("4-14", new Integer[]{1, 2, 3});
        betMethodMap.put("4-15", new Integer[]{1, 2, 3, 4});
        betMethodMap.put("5-1", new Integer[]{5});
        betMethodMap.put("5-5", new Integer[]{4});
        betMethodMap.put("5-6", new Integer[]{4, 5});
        betMethodMap.put("5-10", new Integer[]{2});
        betMethodMap.put("5-15", new Integer[]{1, 2});
        betMethodMap.put("5-16", new Integer[]{3, 4, 5});
        betMethodMap.put("5-20", new Integer[]{2, 3});
        betMethodMap.put("5-25", new Integer[]{1, 2, 3});
        betMethodMap.put("5-26", new Integer[]{2, 3, 4, 5});
        betMethodMap.put("5-30", new Integer[]{1, 2, 3, 4});
        betMethodMap.put("5-31", new Integer[]{1, 2, 3, 4, 5});
        betMethodMap.put("6-1", new Integer[]{6});
        betMethodMap.put("6-6", new Integer[]{5});
        betMethodMap.put("6-7", new Integer[]{5, 6});
        betMethodMap.put("6-15", new Integer[]{2});
        betMethodMap.put("6-20", new Integer[]{3});
        betMethodMap.put("6-21", new Integer[]{1, 2});
        betMethodMap.put("6-22", new Integer[]{4, 5, 6});
        betMethodMap.put("6-35", new Integer[]{2, 3});
        betMethodMap.put("6-41", new Integer[]{1, 2, 3});
        betMethodMap.put("6-42", new Integer[]{3, 4, 5, 6});
        betMethodMap.put("6-50", new Integer[]{2, 3, 4});
        betMethodMap.put("6-56", new Integer[]{1, 2, 3, 4});
        betMethodMap.put("6-57", new Integer[]{2, 3, 4, 5, 6});
        betMethodMap.put("6-62", new Integer[]{1, 2, 3, 4, 5});
        betMethodMap.put("6-63", new Integer[]{1, 2, 3, 4, 5, 6});
        betMethodMap.put("7-1", new Integer[]{7});
        betMethodMap.put("7-7", new Integer[]{6});
        betMethodMap.put("7-8", new Integer[]{6, 7});
        betMethodMap.put("7-21", new Integer[]{5});
        betMethodMap.put("7-35", new Integer[]{4});
        betMethodMap.put("7-120", new Integer[]{2, 3, 4, 5, 6, 7});
        betMethodMap.put("7-127", new Integer[]{1, 2, 3, 4, 5, 6, 7});
        betMethodMap.put("8-1", new Integer[]{8});
        betMethodMap.put("8-8", new Integer[]{7});
        betMethodMap.put("8-9", new Integer[]{7, 8});
        betMethodMap.put("8-28", new Integer[]{6});
        betMethodMap.put("8-56", new Integer[]{5});
        betMethodMap.put("8-70", new Integer[]{4});
        betMethodMap.put("8-247", new Integer[]{2, 3, 4, 5, 6, 7, 8});
        betMethodMap.put("8-255", new Integer[]{1, 2, 3, 4, 5, 6, 7, 8});
    }

    /**
     * 说    明：
     *
     * @param matchNum 场次个数
     * @param isdg     是否支持单关
     *                 创 建 人：	一刀·胡
     *                 创建时间：	2018/5/3 16:03
     *                 修 改 人：
     *                 修改日期：
     **/
    public static Map<Integer, List<BallBunch>> getBallBunch(int matchNum, boolean isdg)
    {
        bunchMap.get(1).clear();
        bunchMap.get(2).clear();
        if (isdg)
        {
            bunchMap.get(1).add(new BallBunch("1-1", "单关", false));
        }
        bunchMap.get(1).addAll(bunchList.get(1).subList(0, matchNum - 1));
        for (int m = 3; m <= matchNum; m++)
        {
            bunchMap.get(2).addAll(bunchList.get(m));
        }
        return bunchMap;
    }

    /**
     * 说    明：   计算投注注数
     *
     * @param betBunchs 选择的串玩法
     * @param list      投注场次和投注号码
     *                  创 建 人：	一刀·胡
     *                  创建时间：	2018/5/14 10:55
     *                  修 改 人：
     *                  修改日期：
     **/
    public static Integer betNum(String[] betBunchs, Object[][] list)
    {
        Combination cb = new Combination(list);
        int num = 0;
        for (String betBunch : betBunchs)
        {
            Integer[] bunch = betMethodMap.get(betBunch);
            if (null != bunch)
            {
                for (Integer m : bunch)
                {
                    List<Object[][]> cm = cb.select(m);
                    for (Object[][] arr : cm)
                    {
                        int _zNum = 1;
                        for (int i = 0; i < arr.length; i++)
                        {
                            _zNum *= arr[i].length;
                        }
                        num += _zNum;
                    }
                }
            }
        }
        return num;
    }

    /**
     * 说    明：   根据单场的投注号获取投注赔率的最小值和最大值
     * 创 建 人：	一刀·胡
     * 创建时间：	2018/5/14 11:39
     * 修 改 人：
     * 修改日期：
     **/
    public static Double[] getMinMaxOdds(Integer[] betNum, Map<String, String> oddsMap)
    {
        Double min = Double.parseDouble(oddsMap.get(betNum[0] + ""));
        Double max = 0.0;
        Map<Integer, Double> betMap = new HashMap<>();
        for (Integer num : betNum)
        {
            String s = oddsMap.get(num + "");
            if (null != s)
            {
                Double d = Double.parseDouble(s);
                if (min > d)
                    min = d;
                betMap.put(num, d);
            }
        }
        max += getMaxOdds(spfKey, betMap);//胜平负
        max += getMaxOdds(rqspfKey, betMap);//让球胜平负
        max += getMaxOdds(bqcKey, betMap);//半全场
        max += getMaxOdds(bfKey, betMap);//比分
        max += getMaxOdds(zjqKey, betMap);//总进球
        return new Double[]{min, max};
    }

    /**
     * 说   明： 根据单场的投注号获取投注赔率的最小值和最大值
     * 作   者：	Guojing
     * 创建时间：	2018/11/23 20:36
     *
     * @param betNum  选中的串法值
     * @param oddsMap 选中场次的玩法map
     **/
    public static Double[] getMinMaxOdds2(Integer[] betNum, Map<Integer, String> oddsMap)
    {
        Double min = Double.parseDouble(oddsMap.get(betNum[0]));
        Double max = 0.0;
        Map<Integer, Double> betMap = new HashMap<>();
        for (Integer num : betNum)
        {
            String s = oddsMap.get(num);
            if (null != s)
            {
                Double d = Double.parseDouble(s);
                if (min > d)
                    min = d;
                betMap.put(num, d);
            }
        }
        max += getMaxOdds(spfKey, betMap);//胜平负
        max += getMaxOdds(rqspfKey, betMap);//让球胜平负
        max += getMaxOdds(bqcKey, betMap);//半全场
        max += getMaxOdds(bfKey, betMap);//比分
        max += getMaxOdds(zjqKey, betMap);//总进球
        return new Double[]{min, max};
    }

    /**
     * 说    明：   根据玩法获取投注最大值
     * 创 建 人：	一刀·胡
     * 创建时间：	2018/5/14 11:41
     * 修 改 人：
     * 修改日期：
     **/
    public static Double getMaxOdds(Integer[] key, Map<Integer, Double> betMap)
    {
        Double _max = 0.0;
        for (Integer num : key)
        {
            Double d = betMap.get(num);
            if (null != d && d > _max)
            {
                _max = d;
            }
        }
        return _max;
    }

    /**
     * 说    明：  最小获奖值
     * 创 建 人：	一刀·胡
     * 创建时间：	2018/5/14 12:49
     * 修 改 人：
     * 修改日期：
     **/
    public static Double betMinVal(String[] betBunchs, List<Double[]> list)
    {
        List<Integer> numList = new ArrayList<>();
        for (String betBunch : betBunchs)
        {
            Integer[] bunch = betMethodMap.get(betBunch);
            if (null != bunch)
            {
                numList.addAll(Arrays.asList(bunch));
            }
        }
        if (numList.size() == 0)
            return 0.00;
        Collections.sort(numList);
//        numList.ss;
        //获取最小值列表并排序
        List<Double> minList = new ArrayList<>();
        for (Double[] d : list)
        {
            List<Double> _minList = new ArrayList<>();
            for (Double _d : d)
            {
                _minList.add(_d);
            }
            Collections.sort(_minList);
            minList.add(_minList.get(0));
        }
        Collections.sort(minList);
        Double val = 2.0;

        for (int i = 0; i < numList.get(0); i++)
        {
            val *= minList.get(i);
        }
        return val;
    }

    /**
     * 说    明：   最大获奖值
     * 创 建 人：	一刀·胡
     * 创建时间：	2018/5/14 12:49
     * 修 改 人：
     * 修改日期：
     **/
    public static Double betMaxVal(String[] betBunchs, List<Double[]> list)
    {
        Double max = 0.0;
        Double[] _max = new Double[list.size()];
        for (int i = 0; i < list.size(); i++)
        {
            _max[i] = list.get(i)[1];
        }
        Combination cb = new Combination(_max);
        for (String betBunch : betBunchs)
        {
            Integer[] bunch = betMethodMap.get(betBunch);
            if (null != bunch)
            {
                for (Integer m : bunch)
                {
                    List<Double[]> cm = cb.select(m);
                    for (Double[] arr : cm)
                    {
                        Double d = 2.0;
                        for (Double _d : arr)
                            d *= _d;
                        max += d;
                    }
                }
            }
        }
        return max;
    }

    /**
     * 说   明： 获取投注获胜的最小场次
     * 作   者：	Guojing
     * 创建时间：	2018/11/24 10:16
     *
     * @param betBunchs 选中的串法值
     * @return 最小场次
     */
    public static Integer bunchNum(String[] betBunchs)
    {
        Set<Integer> set = new HashSet<>();
        for (String betBunch : betBunchs)
        {
            Integer[] bunch = betMethodMap.get(betBunch);
            if (null != bunch)
            {
                for (Integer m : bunch)
                    set.add(m);
            }
        }
        List<Integer> list = new ArrayList<>();
        for (Integer i : set)
            list.add(i);
        return list.size() > 0 ? list.get(0) : 2;
    }
}
